package com.gnerv.pabu.basic.core.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gnerv.pabu.basic.core.dto.MenuDTO;
import com.gnerv.pabu.basic.core.dto.MenuSaveDTO;
import com.gnerv.pabu.basic.core.dto.MenuSearchDTO;
import com.gnerv.pabu.basic.core.dto.MenuTreeDTO;
import com.gnerv.pabu.basic.core.entity.Menu;
import com.gnerv.pabu.basic.core.exception.BusinessException;
import com.gnerv.pabu.basic.core.mapper.MenuMapper;
import com.gnerv.pabu.basic.core.service.IMenuService;
import com.gnerv.pabu.basic.core.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 基础平台-菜单表 服务实现类
 *
 * @author zhang
 * @date 2019/11/29
 **/
@Service
@Slf4j
public class MenuServiceImpl implements IMenuService {

    private final static String ROOT_ID = "0";
    private final static String SYSTEM = "0";
    private final static String CATALOG = "1";
    private final static String MENU = "2";
    private final static String BUTTON = "3";

    @Resource
    private MenuMapper menuMapper;

    @Override
    public boolean saveMenu(MenuSaveDTO menuSaveDTO) {
        String ukId = menuSaveDTO.getUkId();
        if (StringUtils.isEmpty(ukId)) {
            this.createMenu(menuSaveDTO);
        } else {
            this.updateMenu(menuSaveDTO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean createMenu(MenuSaveDTO menuSaveDTO) {
        Menu menu = menuSaveDTO.convert();
        this.checkMenuType(menu);
        menu.setUkId(UUIDUtils.getLower());
        menuMapper.createMenu(menu);

        List<String> permissionIds = menuSaveDTO.getPermissionIds();
        if (!CollectionUtils.isEmpty(permissionIds)) {
            this.bindMenuPermission(menu.getUkId(), permissionIds);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean deleteMenu(String menuId) {
        if (this.hasChildren(menuId)) {
            throw new BusinessException(BusinessException.MENU_HAS_CHILDREN);
        }
        this.unBindMenuPermission(menuId);
        menuMapper.deleteMenu(menuId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateMenu(MenuSaveDTO menuSaveDTO) {
        Menu menu = menuSaveDTO.convert();
        this.checkMenuType(menu);
        menu.setGmtModified(LocalDateTime.now());
        menuMapper.updateById(menu);

        List<String> permissionIds = menuSaveDTO.getPermissionIds();
        if (!CollectionUtils.isEmpty(permissionIds)) {
            this.unBindMenuPermission(menu.getUkId());
            this.bindMenuPermission(menu.getUkId(), permissionIds);
        }

        return true;
    }

    @Override
    public MenuDTO selectMenu(String menuId) {
        return menuMapper.selectMenu(menuId);
    }

    @Override
    public List<MenuTreeDTO> listMenuTree(String parentId) {
        return menuMapper.listMenuTree(parentId);
    }

    @Override
    public Page<MenuDTO> listMenu(MenuSearchDTO searchDTO, Integer current, Integer size) {
        Page<MenuDTO> menuPage = menuMapper.listMenu(new Page<>(current, size), searchDTO);
        return menuPage;
    }

    @Override
    public List<MenuDTO> listSystemByUserId(String userId) {
        List<MenuDTO> menus = menuMapper.listSystemByUserId(userId);
        return menus;
    }

    @Override
    public List<MenuTreeDTO> listMenuTreeByUser(String systemId, String userId) {
        List<MenuTreeDTO> menuTrees = menuMapper.listMenuTreeByUser(systemId, userId);
        return menuTrees;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean bindMenuPermission(String menuId, List<String> permissionIds) {
        menuMapper.bindMenuPermission(menuId, permissionIds);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean unBindMenuPermission(String menuId) {
        menuMapper.unBindMenuPermission(menuId);
        return true;
    }

    @Override
    public boolean hasChildren(String parentId) {
        Long hasChildren = menuMapper.hasChildren(parentId);
        return hasChildren > 0L;
    }

    @Override
    public boolean checkMenuType(Menu menu) {
        return true;
    }

    @Override
    public boolean updateMenuStatus(String menuId, Integer status) {
        menuMapper.updateMenuStatus(menuId, status);
        return true;
    }

    @Override
    public List<MenuTreeDTO> listMenuTreeBySystemIdAndUserId(String systemId, String userId) {
        List<MenuTreeDTO> menuTree = menuMapper.listMenuTreeBySystemIdAndUserId(systemId, userId);
        return menuTree;
    }
}
